<?php
namespace Console\OBD;

use Console\Config\Base;
use Swoole\Process;
use Swoole\Server;
use Redis;

class ServerTask extends Base
{
    /**
     * @var \Swoole\Server
     */
    private $server;
    /**
     * @var Event
     */
    private $event;
    /**
     * @var Redis
     */
    private static $redis;
    /**
     * @var string 存储fd的队列
     */
    public static $connectionSet = 'ws';

    public function initialize()
    {
        $this->event = new Event();
    }

    public function mainAction()
    {
        $this->server = $server = new Server('0.0.0.0', 9580, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
        $this->server->set([
            'reactor_num' => 2,
            'work_num'    => 4,
            'max_request' => 128,
            //            'open_eof_check' => true,
            'daemonize'   => false,
            //            'package_eof'    => 0x29,
            //            'heartbeat_idle_time'      => 10,
            //            'heartbeat_check_interval' => 10
        ]);
        //客户端
        $this->server->on('connect', function (Server $server, int $fd, int $reactorId)
        {
            self::redis()->zAdd(self::$connectionSet, $fd, $fd);
        });
        //        $process = new \swoole_process(function (Process $process) use ($server)
        //        {
        //            foreach ($server->connection_list() as $item) {
        //                var_dump($item);
        //            }
        //        });
        //        $this->server->addProcess($process);
        $server->on('receive', function (Server $server, int $fd, int $from_id, string $data)
        {
            $this->event->dispatcher($server, $fd, $from_id, $data);
        });
        $this->server->on('close', function (Server $server, int $fd, int $reactorId)
        {
            self::redis()->zRem(self::$connectionSet, $fd);
        });
        $this->server->on('WorkerStart', function (Server $server, int $workId)
        {
            if ($workId == 0) {
                //30秒发送一次心跳检测
                $server->tick(60000, function () use ($server)
                {
                    foreach ($server->connections as $fd) {
                        $this->event->heartbeat($server, $fd);
                    }
                });
            }
        });
        //Task任务
        $this->server->on('task', function ()
        {

        });
        //Task完成
        $this->server->on('finish', function ()
        {
        });

        $this->server->start();
    }

    /**
     * @return \Redis
     * @throws \Exception
     */
    public static function redis()
    {
        if (is_null(self::$redis)) {
            self::$redis = new Redis();
            self::$redis->pconnect('127.0.0.1');
            return self::$redis;
        }
        try {
            if (self::$redis->ping() == '+PONG') {
                return self::$redis;
            } else {
                self::$redis = new Redis();
                self::$redis->pconnect('127.0.0.1');
                return self::redis();
            }
        } catch (\Exception $ex) {
            throw new \Exception('链接缓存服务器失败');
        }
    }

    /**
     *
     */
    protected function pAction()
    {
        $process = new \swoole_process(function (Process $process)
        {
            $process->write("hello \n");
        });
        $process->start();

        usleep(100);
        echo $process->read();
    }

    /**
     * 检测是否是TCP客户端
     *
     * @param        $client
     * @param Server $server
     *
     * @return bool
     */
    public static function isTcpClient($client, Server $server)
    {
        $info = $server->getClientInfo($client);
        if (is_array($info) && count($info) > 0) {
            return true;
        }
        return false;
    }

}
